/*
 * Copyright (c) 2020, China Mobile Communications Group Co.,Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-12-09     cmcc       the first version
 */
#include "ns_log.h"

#include <stdio.h>
#include <string.h>

#include <os_stddef.h>
#include <os_assert.h>
#include <os_errno.h>
#include <os_memory.h>
#include <cJSON.h>

#include "httpUtil.h"
#include "UrlEncode.h"

#include "ns_text_semantic.h"

static int check_json(cJSON *json);

/**
 * Text translation.
 *
 * @param token authorize token
 * @param content content of text to translate
 * @param type translation type, such as Chinese to English
 * @param result NS_Text_Translation
 * @return the result of translation, OS_EOK if success, else -OS_ERROR
 */
int ns_text_translation(char *token, char *content, enum TEXT_TRANSLATE_TYPE type, NS_Text_Translation *result)
{
    OS_ASSERT(token);
    OS_ASSERT(content);
    OS_ASSERT(strlen(content) <= MAX_TEXT_LENGTH);
    OS_ASSERT(result);

    //build url
    char url[200] = {0};
    if (type == NS_TRANS_CHN_TO_ENG)
    {
        strcat(url, URL_CHN_ENG_TRANS);
    }
    else if (type == NS_TRANS_ENG_TO_CHN)
    {
        strcat(url, URL_ENG_CHN_TRANS);
    }
    else
    {
        LOG_EXT_E("not supported translation type");
        return -OS_ERROR;
    }
    strcat(url, "access_token=");
    strcat(url, token);

    cJSON *json = http_post_urlencode(url, "input", content);
    if (check_json(json) != OS_EOK)
    {
        cJSON_Delete(json);
        return -OS_ERROR;
    }

    cJSON *data = cJSON_GetObjectItem(json, "data");
    result->translateResult = strdup(cJSON_GetObjectItem(data, "output")->valuestring);

    cJSON_Delete(json);
    return OS_EOK;
}

/**
 * Text classification.
 *
 * @param token authorize token
 * @param content content of text to translate
 * @param result NS_Text_Classification
 * @return the result of classification, OS_EOK if success, else -OS_ERROR
 */
int ns_text_classification(char *token, char *content, NS_Text_Classification *result)
{
    OS_ASSERT(token);
    OS_ASSERT(content);
    OS_ASSERT(strlen(content) <= MAX_TEXT_LENGTH);
    OS_ASSERT(result);

    //build url
    char url[200] = {0};
    strcat(url, URL_TEXT_CLASSFY);
    strcat(url, "access_token=");
    strcat(url, token);

    cJSON *json = http_post_urlencode(url, "data", content);
    if (check_json(json) != OS_EOK)
    {
        cJSON_Delete(json);
        return -OS_ERROR;
    }

    char *data_str = cJSON_GetObjectItem(json, "data")->valuestring;
    /*stupid! "data":"{\"kind\": \"cookbook\"}"*/
    char sep = ':';
    int start_pos = 0;
    int data_len = strlen(data_str);
    for (int i = 0; i < data_len; i++)
    {
        if (*(data_str + i) == sep)
        {
            start_pos = i;
            start_pos++;
            while ((*(data_str + start_pos) == ' ') || (*(data_str + start_pos) == '"'))
            {
                start_pos++;
            }
            break;
        }
    }

    char *kind = os_malloc(20);
    int total = 0;
    for (int i = start_pos; i < (data_len - 2); i++)
    {
        total++;
        *(kind + i - start_pos) = *(data_str + i);
    }
    *(kind + total) = '\0';

    result->kind = kind;

    cJSON_Delete(json);
    return OS_EOK;
}

/**
 * Text keywords.
 *
 * @param token authorize token
 * @param content content of text to translate
 * @param result NS_Text_Keyword
 * @return the result of keywords, OS_EOK if success, else -OS_ERROR
 */
int ns_text_keyword(char *token, char *content, NS_Text_Keyword *result)
{
    OS_ASSERT(token);
    OS_ASSERT(content);
    OS_ASSERT(strlen(content) <= MAX_TEXT_LENGTH);
    OS_ASSERT(result);

    //build url
    char url[200] = {0};
    strcat(url, URL_TEXT_KEYWORD);
    strcat(url, "access_token=");
    strcat(url, token);

    cJSON *json = http_post_urlencode(url, "data", content);
    if (check_json(json) != OS_EOK)
    {
        cJSON_Delete(json);
        return -OS_ERROR;
    }

    //parse data
    cJSON *keyword_json = cJSON_GetObjectItem(cJSON_GetObjectItem(json, "data"), "keywords");
    if (keyword_json == OS_NULL)
    {
        LOG_EXT_E("no data elements");
        cJSON_Delete(json);
        return -OS_ERROR;
    }

    NS_Keyword_Item *items = OS_NULL;
    cJSON *element_json = OS_NULL;

    int kw_count = cJSON_GetArraySize(keyword_json);
    if (kw_count > 0)
    {
        items = os_malloc(sizeof(NS_Keyword_Item) * kw_count);
        int index = 0;
        cJSON_ArrayForEach(element_json, keyword_json)
        {
            (items + index)->word = strdup(cJSON_GetArrayItem(element_json, 0)->valuestring);
            (items + index)->weight = (float)(cJSON_GetArrayItem(element_json, 1)->valuedouble);
            index++;
        }
    }

    result->keywordNumber = kw_count;
    result->items = items;

    cJSON_Delete(json);
    return OS_EOK;
}

static int check_json(cJSON *json)
{
    if (json == OS_NULL)
    {
        return -OS_ERROR;
    }

    cJSON *code = cJSON_GetObjectItem(json, "code");
    if (code->valueint != 200)
    {
        LOG_EXT_E("invalid response, code:%d, msg:%s", code->valueint, (cJSON_GetObjectItem(json, "msg"))->valuestring);
        return -OS_ERROR;
    }

    cJSON *data = cJSON_GetObjectItem(json, "data");
    if (data == OS_NULL)
    {
        LOG_EXT_E("no data elements");
        return -OS_ERROR;
    }

    return OS_EOK;
}
